package org.atlantis.evnlib;

import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;

import org.atlantis.evnlib.exception.EventException;
import org.atlantis.evnlib.execution.EventExecutor;
import org.atlantis.evnlib.execution.TaskEventExecutor;
import org.atlantis.evnlib.execution.rejecter.EmptyRejectedTaskHandler;
import org.atlantis.evnlib.execution.rejecter.RejectedTaskHandler;
import org.atlantis.evnlib.task.TaskExceptionHandler;

public enum Events {

	me;

	private AtomicBoolean inited = new AtomicBoolean(false);
	private EventProcessor evnProc;

	public void init() {
		init(new EmptyRejectedTaskHandler());
	}

	public void init(RejectedTaskHandler rejectedTaskHandler) {
		init(new TaskEventExecutor(rejectedTaskHandler));
	}

	public void init(EventExecutor evnExec) {
		if (!inited.compareAndSet(false, true)) throw new EventException(
				"EventProcessor is initialized, do not reinitialize it.");
		evnProc = new EventProcessor(evnExec);
	}

	public void registerListener(Object listener) {
		checkInited();
		evnProc.register(listener);
	}

	public void unregisterListener(Object listener) {
		checkInited();
		evnProc.unregister(listener);
	}

	public void addEvent(EventDef eventDef) {
		checkInited();
		evnProc.addEvent(eventDef);
	}

	public void fireEvent(String eventName, Object param) {
		EventArg eventArg = new EventArg(eventName, param);
		evnProc.fireEvent(eventArg);
	}

	public void setExceptionHandler(TaskExceptionHandler handler) {
		TaskExceptionHandler.HandlerRegister.registHandler(handler);
	}

	public Collection<Runnable> shutdownNow() {
		return evnProc.shutdownNow();
	}

	private void checkInited() {
		if (!inited.get()) throw new EventException("Events has not initialize, do it first.");
	}
}
